using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Sixeyed.CacheAdapter.PipelineComponents.Tests.Properties;
using Microsoft.BizTalk.Message.Interop;
using Winterdom.BizTalk.PipelineTesting;
using Microsoft.BizTalk.Component;
using System.Xml;

namespace Sixeyed.CacheAdapter.PipelineComponents.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class SetMessageCachePropertiesTest
    {
        private struct Namespace
        {
            public const string CacheAdapter = "http://schemas.sixeyed.com/CacheAdapter/2009";
        }

        private ReceivePipelineWrapper _receivePipeline;
        private ReceivePipelineWrapper ReceivePipeline
        {
            get
            {
                if (this._receivePipeline == null)
                {
                    this._receivePipeline = PipelineFactory.CreateEmptyReceivePipeline();
                    XmlDasmComp xmlDasm = new XmlDasmComp();
                    xmlDasm.AllowUnrecognizedMessage = true;
                    this._receivePipeline.AddComponent(xmlDasm, PipelineStage.Disassemble);
                    SetMessageCacheProperties messageCache = new SetMessageCacheProperties();
                    messageCache.IsCacheEnabled = true;
                    messageCache.IsMessageTypeConfigurationEnabled = true;
                    this._receivePipeline.AddComponent(messageCache, PipelineStage.Validate);
                }
                return this._receivePipeline;
            }
        }

        public SetMessageCachePropertiesTest() { }

        [TestMethod]
        public void Execute_ConfiguredMessage()
        {
            IBaseMessage inputMessage = MessageHelper.CreateFromString(Resources.GetXYZMessage);
            MessageCollection outputMessages = this.ReceivePipeline.Execute(inputMessage);
            Assert.AreEqual(1, outputMessages.Count);
            //XYZ message should configured for caching:
            IBaseMessage outputMessage = outputMessages[0];
            object value = outputMessage.Context.Read("IsMessageCacheEnabled", Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(true, (bool)value);
            //with a ten-minute timeout:
            value = outputMessage.Context.Read("MessageCacheLifespan", Namespace.CacheAdapter);
            Assert.AreEqual(new TimeSpan(0, 10, 0), XmlConvert.ToTimeSpan(value.ToString()));
        }

        [TestMethod]
        public void Execute_PartConfiguredMessage()
        {
            IBaseMessage inputMessage = MessageHelper.CreateFromString(Resources.GetABCMessage);
            MessageCollection outputMessages = this.ReceivePipeline.Execute(inputMessage);
            Assert.AreEqual(1, outputMessages.Count);
            //ABC message should configured for caching:
            IBaseMessage outputMessage = outputMessages[0];
            object value = outputMessage.Context.Read("IsMessageCacheEnabled", Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(true, (bool)value);
            //but timeout is not specified, so should be zero value:
            value = outputMessage.Context.Read("MessageCacheLifespan", Namespace.CacheAdapter);
            Assert.AreEqual(TimeSpan.Zero, XmlConvert.ToTimeSpan(value.ToString()));
            Assert.IsFalse(outputMessage.Context.IsPromoted("MessageCacheLifespan", Namespace.CacheAdapter));
        }

        [TestMethod]
        public void Execute_UnknownMessage()
        {
            IBaseMessage inputMessage = MessageHelper.CreateFromString(Resources.UnknownMessage);
            MessageCollection outputMessages = this.ReceivePipeline.Execute(inputMessage);
            Assert.AreEqual(1, outputMessages.Count);
            //unknown message - should not be configured for caching:
            IBaseMessage outputMessage = outputMessages[0];
            object value = outputMessage.Context.Read("IsMessageCacheEnabled", Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(false, (bool)value);
            Assert.IsTrue(outputMessage.Context.IsPromoted("IsMessageCacheEnabled", Namespace.CacheAdapter));
            //and should not have lifespan written;
            value = outputMessage.Context.Read("MessageCacheLifespan", Namespace.CacheAdapter);
            Assert.IsNull(value);
        }
    }
}
